home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / util / libs / graphics3d.lha / src / library / graphics3Df_t.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-17  |  11.1 KB  |  389 lines

  1. /*
  2. **      $VER: graphics3Df_t.c 10.01 (01.11.97)
  3. **
  4. **      External functions for graphics3D.library
  5. **
  6. **      (C) Copyright 97 Patrizio Biancalani
  7. **      All Rights Reserved.
  8. **
  9. **    Note: this code is traslate from the blitzbasic 3d graphics engine 
  10. **          V 0.9 of Maciej R. Gorny.
  11. */
  12.  
  13. #include <exec/types.h>
  14. #include <exec/memory.h>
  15. #include <proto/exec.h>
  16. #include <proto/intuition.h>
  17. #include <intuition/intuition.h>
  18. #include <intuition/screens.h>
  19.  
  20. #include <graphics/rastport.h>
  21. #include <graphics/clip.h>
  22. #include <graphics/regions.h>
  23. #include <graphics/gfx.h>
  24. #include <graphics/gfxmacros.h>
  25. #include <graphics/layers.h>
  26.  
  27. #include "graphics3Dc.h"
  28. #include "graphics3D.h"
  29. #include "graphics3Df_proto.h"
  30. #include "graphics3D2d_proto.h"
  31.  
  32.  /* Please note, that &PovedtBase always resides in register __a6 as well,
  33.     but if we don't need it, we need not reference it here.
  34.  
  35.     Also note, that registers a0, a1, d0, d1 always are scratch registers,
  36.     so you usually should only *pass* parameters there, but make a copy
  37.     directly after entering the function. To avoid problems of kind
  38.     "implementation defined behaviour", you should make a copy of A6 too,
  39.     when it is actually used.
  40.  
  41.     In this example case, scratch register saving would not have been 
  42.     necessary (since there are no other function calls inbetween), but we 
  43.     did it nevertheless.
  44.   */
  45.  
  46. extern void createworldtocamera(struct ambient3d *in);
  47. extern void recalcobj(struct ambient3d *in);
  48. extern long int t_removeobject(struct ambient3d *in);
  49. extern void localtoworld(struct ambient3d *in);
  50. extern void worldtocamera(struct ambient3d *in);
  51. extern void removebackfacesandshade(struct ambient3d *in);
  52. extern void clipobject3d(struct ambient3d *in);
  53. extern void generatepolylist(struct ambient3d *in);
  54. extern struct objectnode *resetobj(struct ambient3d *in);
  55. extern struct objectnode *nextobj(struct ambient3d *in);
  56. extern struct objectnode *pobj(struct ambient3d *in);
  57. extern void aggobj(struct ambient3d *in);
  58. extern void matidentity4x4(struct matrix4x4 *imatrix); 
  59. extern void matzero4x4(struct matrix4x4 imatrix);
  60. extern void matcopy4x4(struct matrix4x4 *s_m,struct matrix4x4 *d_m);
  61. extern void matmult4x4(struct matrix4x4 *a,struct matrix4x4 *b,
  62.         struct matrix4x4 *r);
  63. extern void matmult4x4s(struct matrix4x4 *a,struct matrix4x4 *b,
  64.         struct matrix4x4 *r);
  65. extern void matmult1x4s(struct matrix1x4 *a,struct matrix4x4 *b,
  66.         struct matrix1x4 *r);
  67. extern void makevector3d(struct vertex *a,struct vertex *b,
  68.          struct vector *result);
  69. extern long int vectormag3d(struct vector *a);
  70.  
  71. /**********************************************************/
  72.  
  73. /****************************************************
  74.  ** Routin per la gestione della grafica, in stile **
  75.  ** 2.0                                            ** 
  76.  ** (c) 1994 BIANCA HARD&SOFT Vers:1.00            **
  77.  ****************************************************/
  78.  
  79. /************ FUNZIONI 3D (trasformazioni oggetti) **********************/
  80.  
  81. /************************************************
  82.  ** sposta origine oggetto attuale.           **
  83.  ************************************************
  84.  *** INPUT :                        * 
  85.  * in -> valore > 0 restituito da display3d.    *
  86.  * dx -> valore spostamento su asse x           *
  87.  *       (valore in FIXPOINT).            *
  88.  * dy -> valore spostamento su asse y           *
  89.  *       (valore in FIXPOINT).            *
  90.  * dz -> valore spostamento su asse z           *
  91.  *       (valore in FIXPOINT).            *
  92.  *** OUTPUT:                    *
  93.  * nessuno.                    *
  94.  ************************************************/
  95. void GD_translateobject(in,dx,dy,dz)
  96. REG(a0)struct ambient3d *in;
  97. REG(d0)long int dx;
  98. REG(d1)long int dy;
  99. REG(d2)long int dz;
  100. {
  101. struct objectnode *obj;
  102.  
  103. obj=pobj(in);
  104.  
  105. obj->worldposx+=dx;
  106. obj->worldposy+=dy;
  107. obj->worldposz+=dz;
  108.  
  109. obj->trasf |= 0x02;
  110.  
  111. }
  112.  
  113. /************************************************
  114.  ** posiziona oggetto attuale in modo assoluto.**
  115.  ************************************************
  116.  *** INPUT :                        * 
  117.  * in -> valore > 0 restituito da display3d.    *
  118.  * dx -> valore posizione su asse x             *
  119.  *       (valore in FIXPOINT).            *
  120.  * dy -> valore posizione su asse y             *
  121.  *       (valore in FIXPOINT).            *
  122.  * dz -> valore posizione su asse z             *
  123.  *       (valore in FIXPOINT).            *
  124.  *** OUTPUT:                    *
  125.  * nessuno.                    *
  126.  ************************************************/
  127. void GD_positionobject(in,x,y,z)
  128. REG(a0)struct ambient3d *in;
  129. REG(d0)long int x;
  130. REG(d1)long int y;
  131. REG(d2)long int z;
  132. {
  133. struct objectnode *obj;
  134.  
  135. obj=pobj(in);
  136.  
  137. obj->worldposx=x;
  138. obj->worldposy=y;
  139. obj->worldposz=z;
  140.  
  141. obj->trasf |= 0x02;
  142.  
  143. }
  144.  
  145. /************************************************
  146.  ** riscala oggetto attuale sui tre assi.      **
  147.  ** Lavora SEMPRE sulle coordinate iniziali,   **
  148.  ** quindi occorre cumulare le eventuali varia-**
  149.  ** zioni di scala all'esterno di questa routin**
  150.  ************************************************
  151.  *** INPUT :                        * 
  152.  * in -> valore > 0 restituito da display3d.    *
  153.  * xscale_fact -> valore riscalatura su asse x  *
  154.  *          (valore in FIXPOINT).        *
  155.  * yscale_fact -> valore riscalatura su asse y  *
  156.  *          (valore in FIXPOINT).        *
  157.  * zscale_fact -> valore riscalatura su asse z  *
  158.  *          (valore in FIXPOINT).        *
  159.  *** OUTPUT:                    *
  160.  * nessuno.                    *
  161.  ************************************************/
  162. void GD_scaleobject(in,xscale_fact,yscale_fact,zscale_fact)
  163. REG(a0)struct ambient3d *in;
  164. REG(d0)long int xscale_fact;
  165. REG(d1)long int yscale_fact;
  166. REG(d2)long int zscale_fact;
  167. {
  168. struct objectnode *obj;
  169. struct vertex *vl,*vo;
  170. long int curr_vertex;
  171.  
  172. obj=pobj(in);
  173. vo=obj->vlocal;
  174. vl=obj->vorig;
  175.  
  176. if (xscale_fact==FIXV AND yscale_fact==FIXV AND zscale_fact==FIXV) return(0);
  177. if (obj->trasf&0x01!=NULL) vl=obj->vlocal;
  178.  
  179. for(curr_vertex=0 ; curr_vertex<obj->numverts ; curr_vertex++)
  180.     {
  181.     vo[curr_vertex].x=(vl[curr_vertex].x*xscale_fact) >> SFIXV;
  182.     vo[curr_vertex].y=(vl[curr_vertex].y*yscale_fact) >> SFIXV;
  183.     vo[curr_vertex].z=(vl[curr_vertex].z*zscale_fact) >> SFIXV;
  184.     }
  185.  
  186. obj->trasf |= 0x01;
  187.  
  188. }
  189.  
  190. /************************************************
  191.  ** ruota oggetto attuale sui tre assi .       **
  192.  ** Lavora SEMPRE sulle coordinate iniziali,   **
  193.  ** quindi occorre cumulare le eventuali varia-**
  194.  ** zioni di rot. all'esterno di questa routin **
  195.  ************************************************
  196.  *** INPUT :                        * 
  197.  * in -> valore > 0 restituito da display3d.    *
  198.  * angle_x -> valore rotazione su asse x.       *
  199.  *           (in gradi INTERO)            *
  200.  * angle_y -> valore rotazione su asse y.       *
  201.  *           (in gradi INTERO)            *
  202.  * angle_z -> valore rotazione su asse z.       *
  203.  *           (in gradi INTERO)            *
  204.  *** OUTPUT:                    *
  205.  * nessuno.                    *
  206.  ************************************************/
  207. void GD_rotateobject(in,angle_x,angle_y,angle_z)
  208. REG(a0)struct ambient3d *in;
  209. REG(d0)long int angle_x;
  210. REG(d1)long int angle_y;
  211. REG(d2)long int angle_z;
  212. {
  213. struct objectnode *obj;
  214. struct vertex *vo,*vl;
  215. long int *sin,*cos;
  216. long int i,product;
  217. struct matrix4x4 rotate_x;
  218. struct matrix4x4 rotate_y;
  219. struct matrix4x4 rotate_z;
  220. struct matrix4x4 rot;
  221. struct matrix4x4 temp;
  222.  
  223. obj=pobj(in);
  224. vo=obj->vlocal;
  225. vl=obj->vorig;
  226. if (obj->trasf&0x01 != NULL) vl=obj->vlocal;
  227. sin=in->sintable;
  228. cos=in->costable;
  229.  
  230. product=0;
  231.  
  232. matidentity4x4(&rot);
  233.  
  234. if (angle_x<0 OR angle_x>360)
  235.     {
  236.     angle_x-=(angle_x/360)*360;
  237.     if (angle_x<0) angle_x+=360;
  238.     }
  239.  
  240. if (angle_y<0 OR angle_y>360)
  241.     {
  242.     angle_y-=(angle_y/360)*360;
  243.     if (angle_y<0) angle_y+=360;
  244.     }
  245.  
  246. if (angle_z<0 OR angle_z>360)
  247.     {
  248.     angle_z-=(angle_z/360)*360;
  249.     if (angle_z<0) angle_z+=360;
  250.     }
  251.  
  252. if (angle_x!=0 AND angle_x!=360) product+=4;
  253. if (angle_y!=0 AND angle_y!=360) product+=2;
  254. if (angle_z!=0 AND angle_z!=360) product+=1;
  255.  
  256. switch (product)
  257.     {
  258.     case(1):
  259.         rot.r0c0=cos[angle_z];
  260.         rot.r0c1=sin[angle_z];
  261.         rot.r1c0=-sin[angle_z];
  262.         rot.r1c1=cos[angle_z];
  263.         for(i=0 ; i<obj->numverts ; i++)
  264.             {
  265.             vo[i].x=(vl[i].x*rot.r0c0+vl[i].y*rot.r1c0) >> SFIXV;
  266.             vo[i].y=(vl[i].x*rot.r0c1+vl[i].y*rot.r1c1) >> SFIXV;
  267.             vo[i].z=vl[i].z;
  268.             }
  269.         obj->trasf|=0x01;
  270.         break;
  271.     case(2):
  272.         rot.r0c0=cos[angle_y];
  273.         rot.r0c2=-sin[angle_y];
  274.         rot.r2c0=sin[angle_y];
  275.         rot.r2c2=cos[angle_y];
  276.         for(i=0 ; i<obj->numverts ; i++)
  277.             {
  278.             vo[i].x=(vl[i].x*rot.r0c0+vl[i].z*rot.r2c0) >> SFIXV;
  279.             vo[i].z=(vl[i].x*rot.r0c2+vl[i].z*rot.r2c2) >> SFIXV;
  280.             vo[i].y=vl[i].y;
  281.             }
  282.         obj->trasf|=0x01;
  283.         break;
  284.     case(3):
  285.         rot.r0c0=(cos[angle_y]*cos[angle_z]) >> SFIXV;
  286.         rot.r0c1=(cos[angle_y]*sin[angle_z]) >> SFIXV;
  287.         rot.r0c2=-sin[angle_y];
  288.         rot.r1c0=-sin[angle_z];
  289.         rot.r1c1=cos[angle_z];
  290.         rot.r2c0=(sin[angle_y]*cos[angle_z]) >> SFIXV;
  291.         rot.r2c1=(sin[angle_y]*sin[angle_z]) >> SFIXV;
  292.         rot.r2c2=cos[angle_y];
  293.         for(i=0 ; i<obj->numverts ; i++)
  294.             {
  295.             vo[i].x=(vl[i].x*rot.r0c0 + vl[i].y*rot.r1c0 +
  296.                 vl[i].z*rot.r2c0) >> SFIXV;
  297.             vo[i].y=(vl[i].x*rot.r0c1 + vl[i].y*rot.r1c1 +
  298.                 vl[i].z*rot.r2c1) >> SFIXV;
  299.             vo[i].z=(vl[i].x*rot.r0c2+vl[i].z*rot.r2c2) >> SFIXV;
  300.             }
  301.         obj->trasf|=0x01;
  302.         break;
  303.     case(4):
  304.         rot.r1c1=cos[angle_x];
  305.         rot.r1c2=sin[angle_x];
  306.         rot.r2c1=-sin[angle_x];
  307.         rot.r2c2=cos[angle_x];
  308.         for(i=0 ; i<obj->numverts ; i++)
  309.             {
  310.             vo[i].y=(vl[i].y*rot.r1c1+vl[i].z*rot.r2c1) >> SFIXV;
  311.             vo[i].z=(vl[i].y*rot.r1c2+vl[i].z*rot.r2c2) >> SFIXV;
  312.             vo[i].x=vl[i].x;
  313.             }
  314.         obj->trasf|=0x01;
  315.         break;
  316.     case(5):
  317.         rot.r0c0=cos[angle_z];
  318.         rot.r0c1=sin[angle_z];
  319.         rot.r1c0=(-cos[angle_x]*sin[angle_z]) >> SFIXV;
  320.         rot.r1c1=(cos[angle_x]*cos[angle_z]) >> SFIXV;
  321.         rot.r1c2=sin[angle_x];
  322.         rot.r2c0=(sin[angle_x]*sin[angle_z]) >> SFIXV;
  323.         rot.r2c1=(-sin[angle_x]*cos[angle_z]) >> SFIXV;
  324.         rot.r2c2=cos[angle_x];
  325.         for(i=0 ; i<obj->numverts ; i++)
  326.             {
  327.             vo[i].x=(vl[i].x*rot.r0c0 + vl[i].y*rot.r1c0 +
  328.                 vl[i].z*rot.r2c0) >> SFIXV;
  329.             vo[i].y=(vl[i].x*rot.r0c1 + vl[i].y*rot.r1c1 +
  330.                 vl[i].z*rot.r2c1) >> SFIXV;
  331.             vo[i].z=(vl[i].y*rot.r1c2+vl[i].z*rot.r2c2) >> SFIXV;
  332.             }
  333.         obj->trasf|=0x01;
  334.         break;
  335.     case(6):
  336.         rot.r0c0=cos[angle_y];
  337.         rot.r0c2=-sin[angle_y];
  338.         rot.r1c0=(sin[angle_x]*sin[angle_y]) >> SFIXV;
  339.         rot.r1c1=cos[angle_x];
  340.         rot.r1c2=(sin[angle_x]*cos[angle_y]) >> SFIXV;
  341.         rot.r2c0=(cos[angle_x]*sin[angle_y]) >> SFIXV;
  342.         rot.r2c1=-sin[angle_x];
  343.         rot.r2c2=(cos[angle_x]*cos[angle_y]) >> SFIXV;
  344.         for(i=0 ; i<obj->numverts ; i++)
  345.             {
  346.             vo[i].x=(vl[i].x*rot.r0c0 + vl[i].y*rot.r1c0+
  347.                 vl[i].z*rot.r2c0) >> SFIXV;
  348.             vo[i].y=(vl[i].y*rot.r1c1+vl[i].z*rot.r2c1) >> SFIXV;
  349.             vo[i].z=(vl[i].x*rot.r0c2 + vl[i].y*rot.r1c2 +
  350.                 vl[i].z*rot.r2c2) >> SFIXV;
  351.             }
  352.         obj->trasf|=0x01;
  353.         break;
  354.     case(7):
  355.         matidentity4x4(&rotate_x);
  356.         rotate_x.r1c1=cos[angle_x];
  357.         rotate_x.r1c2=sin[angle_x];
  358.         rotate_x.r2c1=-sin[angle_x];
  359.         rotate_x.r2c2=cos[angle_x];
  360.         matidentity4x4(&rotate_y);
  361.         rotate_y.r0c0=cos[angle_y];
  362.         rotate_y.r0c2=-sin[angle_y];
  363.         rotate_y.r2c0=sin[angle_y];
  364.         rotate_y.r2c2=cos[angle_y];
  365.         matidentity4x4(&rotate_z);
  366.         rotate_z.r0c0=cos[angle_z];
  367.         rotate_z.r0c1=sin[angle_z];
  368.         rotate_z.r1c0=-sin[angle_z];
  369.         rotate_z.r1c1=cos[angle_z];
  370.         matmult4x4s(&rotate_x,&rotate_y,&temp);
  371.         matmult4x4s(&temp,&rotate_z,&rot);
  372.         for(i=0 ; i<obj->numverts ; i++)
  373.             {
  374.             vo[i].x=(vl[i].x*rot.r0c0 + vl[i].y*rot.r1c0 +
  375.                 vl[i].z*rot.r2c0) >> SFIXV;
  376.             vo[i].y=(vl[i].x*rot.r0c1 + vl[i].y*rot.r1c1 +
  377.                 vl[i].z*rot.r2c1) >> SFIXV;
  378.             vo[i].z=(vl[i].x*rot.r0c2+vl[i].y*rot.r1c2+
  379.                 vl[i].z*rot.r2c2) >> SFIXV;
  380.             }
  381.         obj->trasf|=0x01;
  382.         break;
  383.     }
  384.  
  385. }
  386.  
  387.  
  388. /********************* fine *************************/
  389.